package com.briup.pts.service.impl;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.briup.pts.config.exception.ServiceException;
import com.briup.pts.config.property.QrcodeProperty;
import com.briup.pts.config.response.ResultCode;
import com.briup.pts.domain.bean.Animal;
import com.briup.pts.domain.vo.AnimalVO;
import com.briup.pts.mapper.AnimalMapper;
import com.briup.pts.service.AnimalService;
import com.briup.pts.service.HurdlesService;
import com.briup.pts.service.QrcodeService;
import com.briup.pts.service.UploadService;
import com.briup.pts.utils.FileUtil;
import com.briup.pts.utils.UuidUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.List;

@Service
@RequiredArgsConstructor
public class AnimalImpl implements AnimalService {
    private final AnimalMapper animalMapper;
    private final HurdlesService hurdlesService;
    private final QrcodeProperty qrcodeProperty;

    @Qualifier("qiniuUploadServiceImpl")
    private final UploadService uploadService;
    private final QrcodeService qrcodeService;

    @Override
    public AnimalVO findByAnimalId(String animalId) {
        return animalMapper.queryByAnimalId(animalId);
    }

    @Override
    public PageInfo<AnimalVO> pageQueryByConditional(Integer pageNum, Integer pageSize, String aHealthy, String aGender) {
        try(Page<AnimalVO> ignored = PageHelper.startPage(pageNum,pageSize)) {
            List<AnimalVO> animalVOS = animalMapper.queryByConditional(aHealthy,aGender);
            Page<AnimalVO> records = (Page<AnimalVO>) animalVOS;
            return new PageInfo<>(records);
        }
    }

    @Override
    public void saveOrUpdate(Animal animal) {
        // 根据传入的动物对象中是否包含animalId决定是修改还是新增
        // 注意：修改动物时，极有可能要修改栏圈，那么原本的栏圈就需要修改存量；
        // 所以对于修改动物数据，建议先删除该动物数据，在修改该动物数据
        String animalId = animal.getAAnimalId();
        if (StringUtils.hasText(animalId)){
            // animalId不为空，说明需要修改，先对其继续删除
            deleteById(animalId);
        }else {
            // 没有携带Id，表示为新增，又因为动物表的id为由UUID生成的字符串，所以需要我们手动设置
            animal.setAAnimalId(UuidUtil.randomUUID());
        }
        // 将数据插入到动物表中
        animalMapper.addAnimal(animal);
        // 修改栏圈数据
        hurdlesService.changeSavedNum(animal.getAHurdlesId(),1);
    }

    @Override
    public void deleteById(String animalId) {
        //删除动物数据，需要同时完成该动物对应栏圈的修改
        //需要修改动物对应栏圈的已存量，需要先查询出该动物的信息
        Animal animal = animalMapper.queryByIdWithStatus(animalId,null);
        //如果找不到动物信息，抛出异常
        if(animal == null){
            throw new ServiceException(ResultCode.ANIMAL_IS_DELETED);
        }
        //如果动物没有被删除，那么将其删除，同时修改栏圈
        animalMapper.deleteById(animalId);
        hurdlesService.changeSavedNum(animal.getAHurdlesId(),-1);
        // 动物删除后，还应该删除对应的二维码信息
        qrcodeService.deleteByAnimalId(animalId);


    }

    @Override
    @Transactional
    public void batchDelete(List<String> animalIds) {
        animalIds.forEach(this::deleteById);
    }
    @Override
    public void qrCode(String animalId) {
        // 先根据id查询动物，确保该动物存在
        Animal animal = animalMapper.queryByIdWithStatus(animalId, null);
        if (animal==null){
            throw new ServiceException(ResultCode.ANIMAL_IS_DELETED);
        }

        // 生成二维码
        // 设置二维码中存储的数据内容，即溯源页面的链接，扫描二维码即前往溯源信息的页面
        String content = String.format(qrcodeProperty.getContent(),animalId);
        // 设置二维码在本地中存储的文件对象
        File file = new File(String.format(qrcodeProperty.getBasePath(),
                System.currentTimeMillis()));
        QrCodeUtil.generate(content,300,300,file);

        // 将二维码图片文件上传到七牛云服务器中，得到二维码图片的url地址
        String url = uploadService.upload(FileUtil.convert(file));

        // 将动物id和二维码url地址的关系维护到数据库表中
        qrcodeService.addQrcode(animalId,url);

        // 将本地文件删除
        boolean ignored = file.delete();
    }
}
